/**
 * Permutation.java
 * @author: liuex
 * 2008-3-10 ����04:46:56
 *
 * note: 
 */
package org.lex.math.pc;

import java.lang.reflect.Array;
import java.util.Collection;

import org.lex.utils.functor.UnaryFunctor;


public class Permutation<T> {
	private T[] src = null;
	private int r = 0;

	public Permutation(int r, T... src) {
		this(src, r);
	}

	@SuppressWarnings("unchecked")
	public Permutation(int r, Collection<T> src) {
		this((T[]) src.toArray(), r);
	}

	private Permutation(T[] src, int r) {
		this.src = src;
		this.r = r;
	}

	@SuppressWarnings("unchecked")
	public void visit(UnaryFunctor<?, T[]> functor) {
		T[] perm = (T[]) Array.newInstance(src.getClass().getComponentType(), r);
		int[] used = new int[src.length];
		this.visitPermutation(perm, used, 0, functor);
	}

	private void visitPermutation(T[] perm, int[] used, int pos, UnaryFunctor<?, T[]> functor) {
		int i;
		if (pos == r) {
			functor.operate(perm);
			return;
		}
		for (i = 0; i < src.length; i++) {
			if (0 == used[i]) {
				perm[pos] = src[i];
				used[i]++;
				visitPermutation(perm, used, pos + 1, functor);
				used[i]--;
			}
		}
	}
}
